import pygame
import time
import random

# 初始化Pygame
pygame.init()

# 定义颜色
white = (255, 255, 255)  # 白色
yellow = (255, 255, 102)  # 浅黄色
black = (0, 0, 0)  # 黑色
red = (213, 50, 80)  # 红色
green = (0, 255, 0)  # 绿色
blue = (50, 153, 213)  # 浅蓝色

# 定义显示窗口大小
dis_width = 800  # 窗口宽度
dis_height = 600  # 窗口高度

# 创建显示窗口
dis = pygame.display.set_mode((dis_width, dis_height))  # 设置显示窗口大小
pygame.display.set_caption('贪吃蛇游戏')  # 设置窗口标题

# 定义时钟
clock = pygame.time.Clock()  # 创建时钟对象

snake_block = 10  # 蛇的每个方块大小
snake_speed = 15  # 蛇的速度

# 加载蛇的头部和身体图片
snake_head_img = pygame.image.load('snake_head.png')  # 加载蛇头图片
snake_body_img = pygame.image.load('snake_body.png')  # 加载蛇身图片

# 调整图片大小以适应蛇块大小
snake_head_img = pygame.transform.scale(snake_head_img, (snake_block, snake_block))  # 缩放蛇头图片
snake_body_img = pygame.transform.scale(snake_body_img, (snake_block, snake_block))  # 缩放蛇身图片

# 定义字体样式
font_style = pygame.font.SysFont(None, 50)  # 游戏结束信息字体
score_font = pygame.font.SysFont(None, 35)  # 得分字体

class Snake:
    def __init__(self, block_size):
        self.block_size = block_size  # 蛇块大小
        self.x = dis_width / 2  # 初始x坐标
        self.y = dis_height / 2  # 初始y坐标
        self.x_change = 0  # x方向变化量
        self.y_change = 0  # y方向变化量
        self.body = [[self.x, self.y]]  # 蛇的身体列表
        self.length = 1  # 蛇的长度
        self.direction = 'right'  # 初始方向

    def move(self):
        if self.direction == 'left':  # 如果方向是左
            self.x_change = -self.block_size  # x方向减少一个方块大小
            self.y_change = 0  # y方向不变
        elif self.direction == 'right':  # 如果方向是右
            self.x_change = self.block_size  # x方向增加一个方块大小
            self.y_change = 0  # y方向不变
        elif self.direction == 'up':  # 如果方向是上
            self.y_change = -self.block_size  # y方向减少一个方块大小
            self.x_change = 0  # x方向不变
        elif self.direction == 'down':  # 如果方向是下
            self.y_change = self.block_size  # y方向增加一个方块大小
            self.x_change = 0  # x方向不变

        self.x += self.x_change  # 更新x坐标
        self.y += self.y_change  # 更新y坐标
        self.body.append([self.x, self.y])  # 将新位置添加到身体列表

        if len(self.body) > self.length:  # 如果身体长度超过设定长度
            del self.body[0]  # 删除最早的段落

    def draw(self, surface):
        for i, segment in enumerate(self.body):  # 遍历身体的所有段落
            if i == 0:  # 如果是头部
                # Draw head
                rotated_head = pygame.transform.rotate(snake_head_img, self.get_rotation())  # 根据方向旋转头部图片
                surface.blit(rotated_head, [segment[0], segment[1]])  # 绘制头部图片
            else:
                # Draw body
                surface.blit(snake_body_img, [segment[0], segment[1]])  # 绘制身体图片

    def check_collision(self):
        if self.x >= dis_width or self.x < 0 or self.y >= dis_height or self.y < 0:  # 检查是否撞墙
            return True  # 返回True表示碰撞
        for segment in self.body[:-1]:  # 检查是否撞到自己
            if segment == [self.x, self.y]:
                return True  # 返回True表示碰撞
        return False  # 返回False表示没有碰撞

    def get_rotation(self):
        if self.direction == 'right':  # 如果方向是右
            return 0  # 不旋转
        elif self.direction == 'left':  # 如果方向是左
            return 180  # 旋转180度
        elif self.direction == 'up':  # 如果方向是上
            return 90  # 旋转90度
        elif self.direction == 'down':  # 如果方向是下
            return 270  # 旋转270度

def message(msg, color):
    mesg = font_style.render(msg, True, color)  # 渲染消息文本
    dis.blit(mesg, [dis_width / 6, dis_height / 3])  # 在屏幕上绘制消息文本

def gameLoop():
    game_over = False  # 游戏结束标志
    game_close = False  # 游戏关闭标志

    snake = Snake(snake_block)  # 创建蛇对象

    foodx = round(random.randrange(0, dis_width - snake.block_size) / 10.0) * 10.0  # 食物随机x坐标
    foody = round(random.randrange(0, dis_height - snake.block_size) / 10.0) * 10.0  # 食物随机y坐标

    while not game_over:

        while game_close == True:
            dis.fill(blue)  # 填充背景颜色
            message("You Lost! Press Q-Quit or C-Play Again", red)  # 显示游戏结束信息
            pygame.display.update()  # 更新屏幕

            for event in pygame.event.get():  # 获取事件
                if event.type == pygame.KEYDOWN:  # 如果是按键事件
                    if event.key == pygame.K_q:  # 如果按下Q键
                        game_over = True  # 设置游戏结束标志为True
                        game_close = False  # 设置游戏关闭标志为False
                    if event.key == pygame.K_c:  # 如果按下C键
                        gameLoop()  # 重新开始游戏

        for event in pygame.event.get():  # 获取事件
            if event.type == pygame.QUIT:  # 如果是退出事件
                game_over = True  # 设置游戏结束标志为True
            if event.type == pygame.KEYDOWN:  # 如果是按键事件
                if event.key == pygame.K_LEFT and snake.direction != 'right':  # 如果按下左键且当前方向不是右
                    snake.direction = 'left'  # 改变方向为左
                elif event.key == pygame.K_RIGHT and snake.direction != 'left':  # 如果按下右键且当前方向不是左
                    snake.direction = 'right'  # 改变方向为右
                elif event.key == pygame.K_UP and snake.direction != 'down':  # 如果按下上键且当前方向不是下
                    snake.direction = 'up'  # 改变方向为上
                elif event.key == pygame.K_DOWN and snake.direction != 'up':  # 如果按下下键且当前方向不是上
                    snake.direction = 'down'  # 改变方向为下

        snake.move()  # 移动蛇

        if snake.check_collision():  # 检查碰撞
            game_close = True  # 设置游戏关闭标志为True

        dis.fill(blue)  # 填充背景颜色
        pygame.draw.rect(dis, green, [foodx, foody, snake.block_size, snake.block_size])  # 绘制食物
        snake.draw(dis)  # 绘制蛇

        pygame.display.update()  # 更新屏幕

        if snake.x == foodx and snake.y == foody:  # 如果蛇吃到食物
            foodx = round(random.randrange(0, dis_width - snake.block_size) / 10.0) * 10.0  # 生成新的食物x坐标
            foody = round(random.randrange(0, dis_height - snake.block_size) / 10.0) * 10.0  # 生成新的食物y坐标
            snake.length += 1  # 增加蛇的长度

        clock.tick(snake_speed)  # 控制帧率

    pygame.quit()  # 退出Pygame
    quit()  # 退出程序

gameLoop()  # 开始游戏循环


